package com.wuyan.web.base.aop;


import com.wuyan.helper.kit.DateHelper;
import com.wuyan.web.base.helper.BaseApi;
import com.wuyan.web.base.helper.NetHelper;
import com.wuyan.web.base.helper.auth.LoginInfo;
import com.wuyan.web.base.helper.mongo.MongodbHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 接口日志切面配置
 */

@Slf4j
@Aspect
@Component
public class ApiLogAop extends BaseApi {

    @Autowired
    private MongodbHelper mongodbHelper;

    /**
     * 在切入点的方法run之前要干的
     *
     * @param joinPoint     j
     * @param logAnnotation 注解信息
     */
    @Before("@annotation(logAnnotation)")
    public void logBeforeController(JoinPoint joinPoint, ApiLogAnnotation logAnnotation) {
        //这个RequestContextHolder是Springmvc提供来获得请求的东西
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        assert requestAttributes != null;
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();

        String accessToken = getAccessToken(request);

        LoginInfo loginInfo = null;
        try {
            loginInfo = StringUtils.isBlank(accessToken) ? null : getLoginInfo(request);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        // 记录下请求内容
        log.info(
                "request info      -> {},{},{},{},{}",
                null == loginInfo ? "visitor" : loginInfo.getAccount().getUsername(),
                NetHelper.getRealIP(request),
                request.getMethod(),
                request.getRequestURL().toString(),
                Arrays.toString(joinPoint.getArgs())
        );

        log.info(
                "class&method      -> {},{}.{}",
                null == loginInfo ? "visitor" : loginInfo.getAccount().getUsername(),
                joinPoint.getSignature().getDeclaringTypeName(),
                joinPoint.getSignature().getName()
        );

        // 持久化
        Map<String, Object> data = new HashMap<>();
        data.put("login", null == loginInfo ? "visitor" : loginInfo.getAccount().getUsername());
        data.put("name", logAnnotation.name());
        data.put("ip", NetHelper.getRealIP(request));
        data.put("method", request.getMethod());
        data.put("url", request.getRequestURL().toString());
        data.put("args", Arrays.toString(joinPoint.getArgs()));
        data.put("create_time", DateHelper.get());

        Map<String, Object> signature = new HashMap<>();
        signature.put("declaringTypeName", joinPoint.getSignature().getDeclaringTypeName());
        signature.put("name", joinPoint.getSignature().getName());

        data.put("signature", signature);

        mongodbHelper.save(data, "req_logs");
    }
}
